﻿using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Tippelde.Services.Accounts;
using Tippelde.Services.Dtos;
using Tippelde.Services.Groups;
using Tippelde.Web.Helpers;
using Tippelde.Web.Models.Group;

namespace Tippelde.Web.Controllers
{
    [Authorize]
    public class GroupController : Controller
    {
        [Dependency]
        public IGroupManager GroupManager { get; set; }
        [Dependency]
        public UserManager UserManager { get; set; }

        public GroupController()
        {
        }

        [Authorize(Roles = "admin")]
        public ActionResult Index()
        {

            return View();
        }

        [Authorize(Roles = "admin")]
        public ActionResult List()
        {
            var model = CacheManager.Current.GetAllGroups();
            return View(model);
        }

        [Authorize(Roles = "admin")]
        public ActionResult ListPartial()
        {
            var model = CacheManager.Current.GetAllGroups();
            return PartialView("List", model);
        }

        [Authorize(Roles = "admin")]
        public ActionResult Create(bool? partial)
        {
            ViewBag.ActionName = "Create";
            if (partial ?? false)
                return PartialView("_EditorPartial");

            return View("Editor");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "admin")]
        public ActionResult Create(GroupHeaderData model)
        {
            if (!ModelState.IsValid)
            {
                ViewBag.ActionName = "Create";
                return View("Editor", model);
            }
            GroupManager.CreateGroup(User.Identity.Name, model.Name, model.ShortName, model.Description);
            CacheManager.Current.InvalidateUserGroups();
            return RedirectToAction("Index");
        }

        [Authorize(Roles = "admin")]
        public ActionResult Edit(int Id, bool? partial)
        {
            
            var groupHeaderData = CacheManager.Current.GetAllGroups().SingleOrDefault(g => g.Id == Id);
            if (groupHeaderData == null)
                return RedirectToAction("Index");
            ViewBag.ActionName = "Edit";
            if (partial ?? false)
                return PartialView("_EditorPartial", groupHeaderData);
            return View("Editor", groupHeaderData);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "admin")]
        public ActionResult Edit(GroupHeaderData model)
        {
            if (!ModelState.IsValid && model.Id!=null)
            {
                ViewBag.ActionName = "Edit";
                return View("Editor", model);
            }
            GroupManager.EditGroup(model);
            CacheManager.Current.InvalidateUserGroups();
            return RedirectToAction("Index");
        }

        [Authorize(Roles = "admin")]
        public ActionResult UserAssign(string Id)
        {
            var model = new UserInGroupsModel
            {
                User = UserManager.GetUserHeaderById(Id) ?? new UserHeaderData(),
                Groups = new List<SelectableGroupHeaderData>()
            };
            if (model.User.UserName != null)
            {
                var allGroups = CacheManager.Current.GetAllGroups();
                var selectedGroups = GroupManager.GetGroupIdsForUser(model.User.UserName);
                foreach (var g in allGroups)
                {
                    model.Groups.Add(new SelectableGroupHeaderData()
                        {
                            Id = g.Id,
                            Name = g.Name,
                            ShortName = g.ShortName,
                            IsSelected = selectedGroups.Contains(g.Id)
                        });
                }
            }
            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "admin")]
        public async Task<ActionResult> UserAssign(string Id, Dictionary<int, bool> model)
        {
            await GroupManager.AssignUserToGroupsAsync(Id, model);
            CacheManager.Current.InvalidateUserGroups();
            return RedirectToAction("UserAssign", "Group", new { Id = Id });
        }

        [Authorize(Roles = "admin")]
        public ActionResult AssignToGroup(int Id)
        {
            var model = new UsersAssignToGroupModel
            {
                Group = GroupManager.GetGroupHeaderById(Id) ?? new GroupHeaderData(),
                Users = new List<SelectableUserHeaderData>()
            };
            if (!String.IsNullOrEmpty(model.Group.Name))
            {
                var allUsers = UserManager.GetAllUsers();
                var selectedUsers = GroupManager.GetUserIdsForGroup(Id);
                var editorUsers = GroupManager.GetEditorUserIdsForGroup(Id);
                foreach (var u in allUsers)
                {
                    model.Users.Add(new SelectableUserHeaderData()
                    {
                        UserId = u.UserId,
                        UserName = u.UserName,
                        FullName = u.FullName,
                        IsSelected = selectedUsers.Contains(u.UserId),
                        IsEditor = editorUsers.Contains(u.UserId),
                    });
                }
            }
            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Roles = "admin")]
        public async Task<ActionResult> AssignToGroup(int Id, Dictionary<string, bool[]> model)
        {
            await GroupManager.AssignToGroupAsync(Id, model);
            CacheManager.Current.InvalidateUserGroups();
            return RedirectToAction("AssignToGroup", "Group", new { Id = Id });
        }


        [Authorize(Roles="admin")]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Delete(int Id)
        {
            GroupManager.DeleteGroup(Id);
            CacheManager.Current.InvalidateUserGroups();
            return RedirectToAction("Index");
        }

    }
}